home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / 80X86 / AMISL092.ZIP / SWITCHAR.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-09-24  |  8.4 KB  |  313 lines

  1. ;-----------------------------------------------------------------------
  2. ; SWITCHAR.ASM    Public Domain 1992,1995 Ralf Brown
  3. ;        You may do with this software whatever you want, but
  4. ;        common courtesy dictates that you not remove my name
  5. ;        from it.
  6. ;
  7. ; Provide the undocumented switch-character services which were removed
  8. ; from MSDOS 5.0.  The TSR is larger than necessary because it is
  9. ; illustrating the use of both private INT 2Dh functions and a private
  10. ; API entry point.
  11. ;
  12. ; Version 0.92
  13. ; LastEdit: 9/24/95
  14. ;-----------------------------------------------------------------------
  15.  
  16.     INCLUDE AMIS.MAC
  17.  
  18.     @Startup 2,00                 ; need DOS 2.00
  19.                     ; this macro also takes care of declaring
  20.                     ; all the segments in the required order
  21.  
  22. ;-----------------------------------------------------------------------
  23. ;
  24. VERSION_NUM equ 005Ch    ; v0.92
  25. VERSION_STR equ "0.92"
  26.  
  27. ;-----------------------------------------------------------------------
  28. ;
  29. ; useful macros
  30. ;
  31. LODSB_ES MACRO
  32.     DB 26h,0ACh    ; LODSB ES:
  33.     ENDM
  34.  
  35. ;-----------------------------------------------------------------------
  36. ; Put the resident code into its own segment so that all the offsets are
  37. ; proper for the new location after copying it into a UMB or down into
  38. ; the PSP.
  39. ;
  40. TSRcode@
  41.  
  42. ;-----------------------------------------------------------------------
  43. ; Declare data storage for the TSR
  44. ;
  45.  
  46. switchar_active  db 1
  47. current_switchar db '/'
  48.  
  49. ;-----------------------------------------------------------------------
  50. ; Define the private API entry point handler
  51. ;
  52. switchar_API proc far
  53.     cmp    al,1
  54.     ja    switchar_API_done
  55.     xchg    byte ptr RESIDENT_CODE:switchar_active,al
  56. switchar_API_done:
  57.     ret
  58. switchar_API endp
  59.  
  60. ;-----------------------------------------------------------------------
  61. ; Define our private INT 2Dh function
  62. ;
  63. private:
  64.     cmp     al,10h            ; INT 2D/AH=mpx/AL=10h is set-state
  65.     jne    not_private_func
  66.     mov    al,bl            ; BL=new state
  67.     push    cs
  68.     call    near ptr switchar_API
  69.     mov    ah,al            ; return previous state
  70.     mov    al,0FFh            ; indicate success
  71.     iret
  72.  
  73. not_private_func:
  74.     mov    al,0            ; indicate not supported
  75.     iret
  76.  
  77. ;-----------------------------------------------------------------------
  78. ; Define our removal code
  79. ;    deactivate, then report that we don't have a resident uninstaller
  80. ;    but are now disabled
  81. ;
  82. remov:
  83.     mov    RESIDENT_CODE:switchar_active,0
  84.     mov    bx,0            ; seg of block to free (will be patched)
  85. ALTMPX$PSP equ word ptr ($-2)        ; magic name of word to be patched with
  86.                     ; actual memory block segment by TSR
  87.                     ; installation code
  88.     mov    al,4            ; no resident remover, now disabled
  89.     ret
  90.  
  91. ;-----------------------------------------------------------------------
  92. ; Declare the interrupt vectors hooked by the program, then set up the
  93. ; Alternate Multiplex Interrupt Spec handler
  94. ; Note: the resident remover must precede the ALTMPX if it defines ALTMPX$PSP
  95. ;    otherwise ALTMPX$PSP will be multiply-defined
  96. ;
  97.     HOOKED_INTS 21h            ; hooking INT 21h in add. to INT 2Dh
  98.     ALTMPX    'Ralf B','SWITCHAR',VERSION_NUM,'Switch-character support',private,switchar_API,,remov,Y
  99.  
  100. ;-----------------------------------------------------------------------
  101. ; Now the meat of the resident portion, the MSDOS interrupt handler.
  102. ; We can save one byte by specifying the hardware reset handler set up by
  103. ; the ALTMPX macro above
  104. ;
  105.     ISP_HEADER 21h,hw_reset_2Dh
  106.     cmp    ah,37h            ; switchar/availdev call?
  107.     jne    use_old_int21
  108.     cmp    switchar_active,0    ; is TSR enabled?
  109.     je    use_old_int21        ; if not, pass through
  110.     cmp    al,1            ; check if switchar call
  111.     ja    use_old_int21        ; if not, pass through
  112.     mov    al,0            ; always return 'success'
  113.     jb    get_switchar
  114. set_switchar:
  115.     mov    current_switchar,dl
  116.     iret
  117.  
  118. get_switchar:
  119.     mov    dl,current_switchar
  120.     iret
  121.  
  122. use_old_int21:
  123.     jmp    ORIG_INT21h
  124.  
  125. TSRcodeEnd@
  126.  
  127. ;-----------------------------------------------------------------------
  128.  
  129. _TEXT SEGMENT 'CODE'
  130.     ASSUME cs:_TEXT,ds:NOTHING,es:NOTHING,ss:NOTHING
  131.  
  132. banner    db 'SWITCHAR v',VERSION_STR,'  Public Domain 1992 Ralf Brown',13,10,'$'
  133. usage    db 'Usage:',9,'SWITCHAR i',9,'install',13,10
  134.     db 9,'SWITCHAR r',9,'remove from memory',13,10
  135.     db 9,'SWITCHAR d',9,"disable TSR but don't unload",13,10
  136.     db 9,'SWITCHAR e',9,'enable TSR',13,10
  137.     db 9,'SWITCHAR <x>',9,'set switch character to <x>',13,10
  138.     db '$'
  139. not_installed_msg db "Not " ;continues on next line
  140. installed_msg     db "Installed.",13,10,"$"
  141. cant_install_msg db "Unable to install.",13,10,"$"
  142. already_inst_msg db "Already installed.",13,10,"$"
  143. cant_remove_msg  db "Can't remove from memory.",13,10,"$"
  144. removed_msg     db "Removed.",13,10,"$"
  145. switchar_set_msg db "Switch character has been set.",13,10,"$"
  146. not_set_msg      db "Switch character has NOT been set.",13,10,"$"
  147. not_supported_msg db "Switch character not supported.",13,10,"$"
  148. enabled_msg     db "SWITCHAR enabled $"
  149. disabled_msg     db "SWITCHAR disabled $"
  150. was_on_msg     db "(was enabled).",13,10,"$"
  151. was_off_msg     db "(was disabled).",13,10,"$"
  152. cant_disable_msg db "Can't disable SWITCHAR.",13,10,"$"
  153.  
  154. entry_point dd ?
  155.  
  156.     @Startup2    Y
  157.     push    ds
  158.     pop    es
  159.     ASSUME    ES:_INIT
  160.     push    cs
  161.     pop    ds
  162.     ASSUME    DS:_TEXT
  163.     ;
  164.     ; say hello 
  165.     ;
  166.     DISPLAY_STRING banner
  167.     mov    bx,1000h        ; set memory block to 64K
  168.     mov    ah,4Ah            ; to have some memory to allocate
  169.     int    21h
  170.     mov    si,81h            ; SI -> commandline
  171.     cld
  172. cmdline_loop:
  173.     lodsb_es
  174.     cmp    al,' '            ; skip blanks and tabs on commandline
  175.     je    cmdline_loop
  176.     cmp    al,9
  177.     je    cmdline_loop
  178.     mov    ah,al            ; remember exact switch character
  179.     and    al,0DFh            ; force to uppercase
  180.     cmp    al,'R'
  181.     je    removing
  182.     cmp    al,'I'
  183.     je    installing
  184.     cmp    al,'E'
  185.     je    enabling
  186.     cmp    al,'D'
  187.     je    disabling
  188.         cmp     ah,' '
  189.     jbe    show_usage
  190.     jmp    set_switch_char
  191.  
  192. show_usage:
  193.     mov    dx,offset _TEXT:usage
  194.     jmp    exit_with_error
  195.  
  196. removing:
  197.     UNINSTALL cant_uninstall
  198.     mov    dx,offset _TEXT:removed_msg
  199. exit_with_message:
  200.     mov    ah,9
  201.     int    21h
  202.         mov     ax,4C00h
  203.     int    21h
  204.  
  205. enabling:
  206.     IF_INSTALLED enable_TSR
  207. not_installed:
  208.     mov    dx,offset _TEXT:not_installed
  209.     jmp    exit_with_error
  210.  
  211. disabling:
  212.     IF_INSTALLED disable_TSR
  213.     jmp    not_installed
  214.  
  215. installing:
  216.     INSTALL_TSR ,BEST,,inst_notify,already_installed,cant_install
  217.  
  218. cant_uninstall:
  219.         mov     dx,offset _TEXT:cant_remove_msg
  220.     jmp short exit_with_error
  221. already_installed:
  222.     mov    dx,offset _TEXT:already_inst_msg
  223. exit_with_error:
  224.     mov    ah,9
  225.     int    21h
  226.     mov    ax,4C01h
  227.     int    21h
  228.  
  229. set_switch_char:
  230.     mov    dl,ah
  231.     push    dx
  232.     mov    ax,3701h
  233.     int    21h
  234.     pop    cx            ; get back requested switch character
  235.     mov    dx,offset _TEXT:not_supported_msg
  236.     cmp    al,0            ; supported?
  237.     jne    set_switch_done        ; branch if not
  238.     mov    ax,3700h
  239.     int    21h            ; get current switch character
  240.     cmp    dl,cl            ; now same as request switch char?
  241.     mov    dx,offset _TEXT:switchar_set_msg
  242.     je    set_switch_done
  243.     mov    dx,offset _TEXT:not_set_msg
  244. set_switch_done:
  245.     jmp    exit_with_message
  246.  
  247. cant_install:
  248.     mov    dx,offset _TEXT:cant_install_msg
  249.     jmp    exit_with_error
  250.  
  251. inst_notify:
  252.     DISPLAY_STRING _TEXT:installed_msg
  253.     ret
  254.  
  255. ;-----------------------------------------------------------------------
  256. ; on entry, AH=multiplex number
  257. ;
  258. ; for this example program, the 'enable' call will be made via a private
  259. ; INT 2Dh function, while the 'disable' call will be made via the FAR
  260. ; CALL entry point.
  261. ;
  262.  
  263. enable_TSR proc
  264.     mov    al,10h            ; private func, "set state"
  265.     mov    bl,1            ; new state = enabled
  266.     int    2Dh            ; set state, returns AH=old state
  267.     mov    al,ah
  268.     mov    dx,offset _TEXT:enabled_msg
  269. display_state_and_exit:
  270.     push    ax            ; remember prior state
  271.     mov    ah,9            ; display string
  272.     int    21h
  273.     pop    ax            ; get back prior state
  274.     mov    dx,offset _TEXT:was_on_msg
  275.     cmp    al,0
  276.     jne    display_state
  277.     mov    dx,offset _TEXT:was_off_msg
  278. display_state:
  279.     jmp    exit_with_message
  280. enable_TSR endp
  281.  
  282. ;-----------------------------------------------------------------------
  283. ; on entry, AH=multiplex number
  284. ;
  285. ; for this example program, the 'enable' call will be made via a private
  286. ; INT 2Dh function, while the 'disable' call will be made via the FAR
  287. ; CALL entry point.
  288. ;
  289.  
  290. disable_TSR proc
  291.     mov    al,1            ; function "get API entry"
  292.     int    2Dh    
  293.     cmp    al,0FFh            ; supported?
  294.     jne    disable_not_supported
  295.     mov    word ptr _TEXT:entry_point+2,dx
  296.     mov    word ptr _TEXT:entry_point,bx
  297.     mov    al,0            ; function is disable
  298.     call    dword ptr _TEXT:entry_point
  299.     mov    dx,offset _TEXT:disabled_msg
  300.     jmp    display_state_and_exit
  301. disable_not_supported:
  302.     mov    dx,offset _TEXT:cant_disable_msg
  303.     jmp    exit_with_error
  304. disable_TSR endp
  305.  
  306. ;-----------------------------------------------------------------------
  307.  
  308. _TEXT ENDS
  309.  
  310.      end INIT
  311.  
  312.  
  313.